﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using PGMHelper;
using System.IO;

namespace PBSD_Development
{
    public static class ExampleDemo
    {
        /// <summary>
        /// 批量生成分析结果数据库
        /// </summary>
        /// <param name="directPath"></param>
        public static void MultiRead(string directPath)
        {
            //路径是否存在
            if (!Directory.Exists(directPath)) return;
            //获得所有OSIDA路径
            var filePathList = WilsonHelper.GetSpecificFiles(directPath, "OSIDA.tcl", true);
            //遍历所有文件
            filePathList.ForEach(path => ReadPEResultDemo(Path.GetDirectoryName(path)));
        }

        /// <summary>
        /// 读取构件弹塑性分析结果例子
        /// </summary>
        /// <param name="dreictPath"> 弹塑性分析结果所在文件夹（PF3DS或tcl所在路径） </param>
        public static void ReadPEResultDemo(string directPath)
        {
            //构造分析结果
            var result = new FEMResultObj(directPath, false);
            //反序列化构件分析结果
            var isSuccess = result.SetElementResult(true);
            //不成功直接返回
            if (!isSuccess) return;
        }

        /// <summary>
        /// 宏观分析结果
        /// </summary>
        /// <param name="directPath"></param>
        public static void ReadGlobalResult(string directPath)
        {
            //构造分析结果
            var result = new FEMResultObj(directPath, false);
            //宏观分析结果
            GlobalResultDemo(result);
        }

        /// <summary>
        /// 单元分析结果
        /// </summary>
        /// <param name="directPath"></param>
        public static void ReadElementResult(string directPath)
        {
            //构造分析结果
            var result = new FEMResultObj(directPath, false);
            //反序列化构件分析结果
            var isSuccess = result.SetElementResult(false);
            //不成功直接返回
            if (!isSuccess) return;
            //宏观分析结果
            ElementResultDemo(result);
        }

        /// <summary>
        /// 结构宏观分析结果
        /// </summary>
        /// <param name="result"> 分析结果对象 </param>
        private static void GlobalResultDemo(FEMResultObj result)
        {
            //获得第一塔楼
            var tower = result.GetFirstTower();
            //所有地震工况
            var loadCaseList = result.GetGroundMotionLoadCaseList();
            //平面包围长度
            var XLength = result.BoundaryXLength();
            var ZLength = result.BoundaryZLength();
            //第一周期
            var period1 = result.GetYJKPeriod(1);

            //X向或Y向分析结果
            bool isX = true;
            //宏观分析结果
            foreach (var loadcase in loadCaseList)
            {
                //最大层间位移角 
                var maxDrift = tower.GetMaxReaction(loadcase, StoreyReaction.Drift);
                //最大层间位移角所在楼层
                var maxDriftIndex = tower.GetMaxDriftStoreyIndex(loadcase);
                //最大楼层残余位移角 
                var resDrift = tower.GetMaxReaction(loadcase, StoreyReaction.ResDrift, isX);
                //顶点位移
                var topDisp = tower.GetTopDisp(loadcase, isX);
                //最大楼层位移 最大楼层加速度
                var maxDisp = tower.GetMaxReaction(loadcase, StoreyReaction.Disp);
                var maxAccel = tower.GetMaxReaction(loadcase, StoreyReaction.Accel);
                //基底剪力 
                var baseShear = tower.GetBottomForce(loadcase, isX);
                //基底倾覆弯矩
                var baseMoment = tower.GetBottomMoment(loadcase, isX);

                //随便拿个楼层举例
                var storey = tower.GetStoreyList().First();
                //楼层最大层间位移角 
                var storey_maxDrift = storey.GetMaxReaction(loadcase, StoreyReaction.Drift, isX);
                //楼层残余层间位移角 
                var storey_resDrift = storey.GetMaxReaction(loadcase, StoreyReaction.ResDrift, isX);
                //最大楼层位移
                var storeyDisp = storey.GetMaxReaction(loadcase, StoreyReaction.Disp, isX);
                //最大楼层加速度
                var storeyAccel = storey.GetMaxReaction(loadcase, StoreyReaction.Accel, isX);
                //最大楼层剪力 
                var storeyShear = storey.GetMaxForce(loadcase, isX);
                //最大楼层倾覆弯矩
                var storeyMoment = storey.GetMaxMoment(loadcase, isX);

            }
        }

        /// <summary>
        /// 构件性能评估结果
        /// </summary>
        /// <param name="result"> 分析结果对象 </param>
        private static void ElementResultDemo(FEMResultObj result)
        {
            //获得第一塔楼
            var tower = result.GetFirstTower();
            //所有地震工况
            var loadCaseList = result.GetGroundMotionLoadCaseList();
            //获得单元组
            ElementGroupSetObj groupSetObj;
            //尝试获得构件结果
            if (!result.GetElementGroupSetObj(out groupSetObj)) return;
            //遍历所有框架单元组
            foreach (var elementGroup in groupSetObj.GetFRAMEGroupList())
            {
                //随便拿个工况举例
                var loadCase = loadCaseList.First();
                //塔楼内单元组构件的性能状态占比
                var performRatioDict = elementGroup.GetStoreyDeformPerformRatio(loadCase, tower);
                //随便拿个楼层举例
                var storey = tower.GetStoreyList().First();
                //楼层内该单元组构件的平均转角
                var avgDeform = storey.GetAVGDeform(loadCase, elementGroup);
                //楼层内该单元组构件的平均需求能力：相对于严重损坏SeriousDMG
                var avgDeformDCR = storey.GetAVGDeformDCR(loadCase, elementGroup, FEM.Result.DeformType.SeriousDMG);
                //楼层内该单元组构件的最大需求能力：相对于严重损坏SeriousDMG
                var maxDeformDCR = storey.GetMaxDeformDCR(loadCase, elementGroup, FEM.Result.DeformType.SeriousDMG);
                //性能状态占比
                var performRatio = storey.GetDeformPerformRatio(loadCase, elementGroup);
                //遍历楼层内的该单元组所有单元
                foreach (var element in elementGroup.GetElementList(storey))
                {
                    //单元节点
                    var nodeList = element.GetNodeList(result.NodeManager);
                    //获得单元变形：控制变形、某端某方向变形(i端绕3轴)
                    var deformCtrl = element.GetDeform(loadCase);
                    var deformCtrl2 = element.GetMaxDeform(loadCase);
                    var deformSpec = element.GetDeform(loadCase, FEM.Result.FRAMReusltDirect.i3);
                    //变形限值：控制变形、某端某方向变形(i端绕3轴)
                    var limitCtrl = element.GetDeformLimits(loadCase);
                    var limitSpec = element.GetDeformLimits(loadCase, FEM.Result.FRAMReusltDirect.j3);
                    //需求能力比：控制变形、某端某方向变形(i端绕3轴)
                    var dcrListCtrl = element.GetDeformDCRList(loadCase);
                    var dcrListSpec = element.GetDeformDCRList(loadCase, FEM.Result.FRAMReusltDirect.j3);
                    //某状态下的需求能力比：控制变形、某端某方向变形(i端绕3轴) ：相对于严重损坏SeriousDMG
                    var dcrCtrl = element.GetDeformDCR(loadCase, FEM.Result.DeformType.SeriousDMG);
                    var dcrSpec = element.GetDeformDCR(loadCase, FEM.Result.FRAMReusltDirect.i3, FEM.Result.DeformType.SeriousDMG);
                }
            }
        }
    }

    /// <summary>
    /// 性能指标插值例子
    /// </summary>
    public static class PerformLimitExampleDemo
    {
        /// <summary>
        /// RC梁
        /// </summary>
        public static void RCBeamDemo()
        {
            //初始化截面：剪跨、轴压
            var section = new FrameSection(2240);
            //定义材料强度
            section.SetRCMaterial(30, 400, 400);
            //定义截面
            section.SetRCRectangularSection(400, 1000, 20);
            //定义纵筋配筋（mm） 顶筋-底筋
            section.SetRectBeamReinforcement(2850, 1600);
            //定义面积配箍率和体积配箍率
            section.SetStirrup(0.0059, 0.008);
            //计算承载力和性能限值
            PerformLimitExampleDemo.CapacityLimitDemo(section);
        }

        /// <summary>
        /// RC柱
        /// </summary>
        public static void RCColumnDemo()
        {
            //初始化截面：剪跨、轴压
            var section = new FrameSection(1720, -2834000);
            //定义材料强度
            section.SetRCMaterialWithFck(20.1, 400, 400);
            //定义截面
            section.SetRCRectangularSection(1000, 1000, 20);
            //定义纵筋配筋（mm）角筋-（X向单侧钢筋-2*角筋）-（Y向单侧钢筋-2*角筋）
            section.SetRectColumnReinforcement(400, 2000, 2000);
            //定义面积配箍率和体积配箍率
            section.SetStirrup(0.0037, 0.008);
            //计算承载力和性能限值
            PerformLimitExampleDemo.CapacityLimitDemo(section);
        }

        /// <summary>
        /// RC墙
        /// </summary>
        public static void RCWallDemo()
        {
            //初始化截面：剪跨、轴压
            var section = new WallSection(5851, -35352000);
            //定义材料强度
            section.SetRCMaterial(60, 400, 400);
            //定义截面
            section.SetWallSection(3875, 700, 775, 581);
            //定义配筋 竖向分布 水平分布 约束边缘构件纵筋 体积配箍率
            section.SetWallReinforcement(0.003, 0.003, 0.012, 0.012, 0.092);
        }

        /// <summary>
        /// SRC柱
        /// </summary>
        public static void SRCColumnDemo()
        {
            //初始化截面：剪跨、轴压
            var section = new FrameSection(3192, -42338000);
            //定义材料强度
            section.SetSRCMaterial(60, 400, 400, 345);
            //定义截面
            section.SetSRCRectangularSection15(1400, 1400, 30, 900, 300, 30, 20);
            //定义纵筋配筋（mm）角筋-（X向单侧钢筋-2*角筋）-（Y向单侧钢筋-2*角筋）
            section.SetRectColumnReinforcement(500, 3450, 3450);
            //定义面积配箍率和体积配箍率
            section.SetStirrup(0.0052, 0.002);
            //计算承载力和性能限值
            PerformLimitExampleDemo.CapacityLimitDemo(section);
        }

        /// <summary>
        /// SRC墙
        /// </summary>
        public static void SRCWallDemo()
        {
            /*RC墙测试*/
            //初始化截面：剪跨、轴压
            var section = new WallSection(5851, -35352000);
            //定义材料强度
            section.SetSRCMaterial(60, 400, 400, 345);
            //定义截面
            section.SetWallSection(3875, 700, 775, 581);
            //定义配筋 竖向分布 水平分布 约束边缘构件纵筋 体积配箍率
            section.SetWallReinforcement(0.003, 0.003, 0.012, 0.012, 0.092);
            //设定约束边缘构件的含钢率
            section.SetWallSteel(0.05, 0.05);
        }

        /// <summary>
        /// 承载力计算和指标插值DEMO
        /// </summary>
        private static void CapacityLimitDemo(Section section)
        {
            //只计算抗剪承载力
            CapacityObj shearCapacityObj;
            if (!section.GetShearCapacityObj(out shearCapacityObj)) return;
            //设定性能状态（加载角度，SRC梁还需提供剪力（N））
            if (!section.SetLimits(true)) return;
            //性能限值
            var limits = section.GetLimits();
            //破坏形态
            var damageMode = section.GetDamageMode();
            //性能状态
            var perform = section.GetPerform(0.017);
            //抗弯抗剪承载力：标准值
            var momentCapacity = section.GetMomentCapacity(CapacityType.BasicValue);
            var shearCapacity = section.GetShearCapacity(CapacityType.BasicValue);
            //弯剪比
            var msr = section.MSR;
            //剪跨比
            var lamda = section.Lammda;
            //轴压系数
            var alr = section.AxialLoadRatio;
        }
    }
}
